package io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

import ui.Standards;

/**
 * The class that contains common database access features.  Individual methods may still
 * need to be defined.
 * 
 * @author Aaron Chen
 * @version 3/17/2014
 */
public abstract class AbstractAccess {

  /** Object required for building document from XML file in JDOM2. */
  private final SAXBuilder my_builder;

  /** File object to hold the XML file. */
  private final File my_xmlfile;

  /** The directory where the file can be found. */
  private final String my_directory;
  
  /** The object that establishes a special input stream to the XML file. */
  private final Document my_doc;
  
  /** The next ID of a new object. */
  private int my_next_id;
  
  
  /**
   * Constructs the access class.
   * @param the_file_name The name of a specific database file that the Access
   *                      class interfaces with.
   * @throws IOException If there is a problem establishing connectivity to the file.
   * @throws JDOMException If the file cannot be correctly parsed.
   */
  protected AbstractAccess(final String the_file_name) throws IOException, JDOMException {
    my_directory = Standards.DATABASE_PATH + the_file_name;
    my_builder = new SAXBuilder();
    my_xmlfile = new File(my_directory);
    my_doc = (Document) my_builder.build(my_xmlfile);
    my_next_id = my_doc.getRootElement().getChildren().size();
  }

  /**
   * Attempts to write to the XML file.
   * 
   * @return true if the operation was a success; false otherwise.
   */
  protected boolean writeToDatabase() {
    boolean result = true;
    try {
      final XMLOutputter out = new XMLOutputter();
      out.setFormat(Format.getPrettyFormat());
      out.output(my_doc, new FileWriter(my_directory));
    } catch (final IOException e) {
      e.printStackTrace();
      result = false;
    }
    return result;
  }
  
  /**
   * Returns the Document object.
   * @return The Document object.
   */
  public final Document getDoc() {
    return my_doc;
  }
  
  /**
   * Returns the number of data elements in the XML file.
   * @return The number of data elements in the XML file.
   */
  public final int getDataSize() {
    return my_next_id;
  }
  
  /**
   * Returns the next available ID number and then increments it.
   * @return The next available ID.
   */
  protected final int getNextID() {
    return my_next_id++;
  }
  
  /**
   * Determines whether a String contains any meaningful content.
   * @param the_str The string to be tested.
   * @return true if the String has a length of at least one; false otherwise.
   */
  protected boolean isNonemptyString(final String the_str) {
    return the_str != null && !the_str.isEmpty();
  }
  
}
